home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
ai
/
neural22
/
slug3.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-04-15
|
41KB
|
1,315 lines
{$F+}
uses objects,owindows,odialogs,strings,win31,windos, wintypes,winprocs,
ostddlgs,bwcc,bpnet2, nnunit2, dyna3,wintools,cfmtools
{$IFDEF DEBUG}
,WINCRT
{$ENDIF}
;
{$I c:\neural\slug3\SLUG3.inc}
{$R c:\neural\slug3\slug3}
const
wm_openthisfile = wm_user + 1; {message to editor to open file}
type
nninitdata = record
inputsize : longint;
outputsize : longint;
hiddensize : longint;
end;
NNLearnparams = record
Lcoeff : double;
momentum : double;
Kmod : double;
Maxerr : double;
Maxiter : longint;
end;
TrainStepRec = record
DMdesired : pdynamat;
DMinput : pdynamat;
DVerror : pdynavec;
end;
Transferfuncrec = record
hiddentanh,hiddensigmoid,hiddenlinear,
outputtanh,outputsigmoid,outputlinear : WORD;
end;
pannpgm = ^ANNpgm;
{----------------------------}
ANNpgm = object(tapplication)
{----------------------------}
procedure Initmainwindow; virtual;
end;
pNNwindow = ^NNwindow;
{----------------------------}
NNWindow = object(tdlgwindow)
{----------------------------}
net : psimplebpnet;
inname : array[0..fspathname] of char;
outname : array[0..fspathname] of char; {these contain a network on stream}
datainname : array[0..fspathname] of char;
logname,
lastlog : array[0..fspathname] of char; {these contain network data}
infile,
outfile : pdosstream; {streams for network}
datainfile,
logfile : text;
initbuffer : nninitdata; {user data}
learnbuffer : NNlearnparams;
funcbuffer : transferfuncrec;
datainopen : boolean; {are the data files open? }
logopen : boolean;
netok,dataok,logok : boolean; {are these specified ?}
modified : boolean; {refers to network spec file}
running : boolean;
training : boolean;
stopped : boolean;
logappend : boolean; {Logfile Append check box}
randomdata : boolean; {Present data randomly}
edmomentum,edlearn, {edit controls in the main dialog box}
edkmod,edmaxerr,
infolearn,
infomomentum : PSTATIC; {pfloatedit; don't need these in BP7...}
edmaxiter : Pstatic; {pnumedit;}
edinfocount : pnumedit;
edinfoerror : pfloatedit;
eddatafile,
edlogfile : Pstatic; {pedit;}
chlogappend,
chrandomdata : pcheckbox;
constructor init(aparent : pwindowsobject; atitle : pchar);
destructor done; virtual;
function canclose : boolean; virtual;
function getclassname : pchar ;virtual;
procedure getwindowclass(var awndclass : twndclass); virtual;
procedure CMnewfile(var mess : tmessage); virtual cm_first +cm_filenew;
procedure CMopenfile(var mess : tmessage); virtual cm_first +cm_fileopen;
procedure CMsavefile(var mess : tmessage); virtual cm_first +cm_filesave;
procedure CMsaveasfile(var mess : tmessage); virtual cm_first +cm_filesaveas;
procedure CMEXit(var mess : tmessage); virtual cm_first +cm_exit;
procedure CMbuildnet(var mess : tmessage); virtual ;
procedure CMdatain(var mess : tmessage); virtual cm_first +cm_datain;
procedure CMdataout(var mess : tmessage); virtual cm_first +cm_dataout;
procedure CMSetTransfer(var mess : tmessage); virtual cm_first+cm_settransfer;
procedure SetTransferFunctions;
procedure CMtrain(var mess : tmessage); virtual cm_first +cm_train;
procedure CMtrainparams(var mess: tmessage); virtual cm_first+ cm_trainedit;
procedure CMrun(var mess : tmessage); virtual cm_first +cm_run;
procedure CMAbout(var mess : tmessage); virtual cm_first +cm_about;
procedure CMSlughelp(var mess : tmessage); virtual cm_first + cm_slughelp;
procedure CMdisplay(var mess : tmessage); virtual cm_first +cm_display;
procedure BNResetweights(var mess : tmessage); virtual id_first+ id_reset;
procedure BNstopnet(var mess : tmessage); virtual id_first+ id_iterstop;
procedure BNsavenet(var mess : tmessage); virtual id_first+ id_savenet;
procedure BNreadnet(var mess : tmessage); virtual id_first+ id_readnet;
procedure BNshakenet(var mess : tmessage); virtual id_first+ id_shake;
procedure BNtrain(var mess : tmessage); virtual id_first+ id_train;
procedure BNSettransfer(var mess : tmessage); virtual id_first+ id_settransfer;
procedure BNdataopen(var mess : tmessage);virtual id_first+id_dataopen;
procedure BNdataclose(var mess : tmessage); virtual id_first+id_dataclose;
procedure BNlogopen(var mess : tmessage); virtual id_first+id_logopen;
procedure BNlogclose(var mess : tmessage); virtual id_first+id_logclose;
procedure BNtrainparams(var mess : tmessage); virtual id_first+id_trainparams;
procedure BNdataedit(var mess : tmessage); virtual id_first+id_dataedit;
procedure BNLogedit(var mess : tmessage); virtual id_first+id_logedit;
procedure CHrandom(var mess : tmessage); virtual id_first+id_random;
procedure EditFile(pathname : pchar);
procedure trainsession;
function trainepoch(var data : trainsteprec; count: word) : double;
procedure setupnetparams;
procedure showtrainparams;
procedure shownetparams;
procedure showicon(state : word);
function closelogfile : boolean;
function closedatafile : boolean;
function killnet : boolean;
procedure report(rep :pchar);
end;
pSpecdialog = ^Specdialog;
{----------------------------}
Specdialog = object(tdialog)
{----------------------------}
procedure zerocounts(var mess : tmessage); virtual
id_first + id_netspecclear;
end;
var tempstr : string;
{--------------------- NNWINDOW PROCEDURES --------------------------}
{----------------------------}
constructor nnwindow.init(aparent : pwindowsobject;
atitle : pchar);
{----------------------------}
begin
tdlgwindow.init(aparent,atitle);
ismodal := false;
if neuralerror <> 0 then
begin
printneuralerror;
exit;
end;
strpcopy(outname,'');
strpcopy(inname,'*.ann');
strpcopy(datainname,'');
strpcopy(logname,'');
strpcopy(lastlog,'');
infile := nil;
outfile := nil;
net := nil;
modified := false;
running := false;
stopped := false;
training := false;
datainopen := false;
logopen := false;
logok := false;
dataok := false;
netok := false;
logappend := false;
with initbuffer do
begin
inputsize := 2;
outputsize := 1;
hiddensize := 2;
end;
with learnbuffer do
begin
lcoeff := 0.5;
momentum := 0.8;
kmod := 0;
maxerr := 0.1;
maxiter := 20000;
end;
{set transferfunction specs}
with funcbuffer do
begin
hiddentanh := BF_unchecked;
hiddensigmoid := BF_checked;
hiddenlinear := BF_unchecked;
outputtanh := BF_unchecked;
outputsigmoid := BF_unchecked;
outputlinear := BF_checked;
end;
{ Initialize the edit controls }
new(edmomentum,initresource(@self,ed_usermomen,6));
new(edlearn,initresource(@self,ed_userlearn,6));
new(edkmod,initresource(@self,ed_userepoch,6));
new(edmaxerr,initresource(@self,ed_usermaxerr,6));
new(edmaxiter,initresource(@self,ed_usermaxiter,6));
new(eddatafile,initresource(@self,ed_userdatafile,20));
new(edlogfile,initresource(@self,ed_userlogfile,20));
new(edinfocount,initresource(@self,ed_infocount,6,1,999));
new(edinfoerror,initresource(@self,ed_infoerror,6,0.0,9999.9));
new(infolearn,initresource(@self,ed_infolearn,6));
new(infomomentum,initresource(@self,ed_infomomen,6));
new(chlogappend,initresource(@self,id_append));
new(chrandomdata,initresource(@self,id_random));
showicon(sw_hide);
end;
{----------------------------}
destructor nnwindow.done;
{----------------------------}
begin
if net <> nil then dispose(net,done);
dispose(edmomentum, done);
dispose(edlearn,done);
dispose(edkmod,done);
dispose(edmaxerr,done);
dispose(edmaxiter,done);
dispose(eddatafile,done);
dispose(edlogfile,done);
dispose(edinfocount,done);
dispose(edinfoerror,done);
dispose(infolearn,done);
dispose(infomomentum,done);
dispose(chlogappend,done);
dispose(chrandomdata,done);
if datainopen then close(datainfile);
if logopen then close(logfile);
tdlgwindow.done;
end;
{----------------------------}
function nnwindow.getclassname : pchar;
{----------------------------}
begin
getclassname := 'neuralnetwindow';
end;
{----------------------------}
procedure nnwindow.getwindowclass(var awndclass : twndclass);
{----------------------------}
begin
tdlgwindow.getwindowclass(awndclass);
awndclass.hicon := loadicon(hinstance,'networkicon');
awndclass.lpszmenuname := 'themenu';
Awndclass.hbrbackground := getstockobject(null_brush);
{Remember to specify the menu in the resource file !}
end;
{----------------------------}
function nnwindow.canclose : boolean;
{----------------------------}
var
reply : integer;
mess : tmessage;
begin
canclose := true;
if training or running then
begin
BNstopnet(mess);
canclose := false;
exit;
end;
if netok and modified then
begin
reply := messagebox(hwindow,'Lose your changes ?','Net has changed...',
mb_yesno or mb_iconquestion);
if reply = idno then
canclose := false
else
begin
canclose := true;
if net <> nil then
begin
dispose(net,done);
net := nil;
netok := false;
showicon(sw_hide);
end;
end;
end;
end;
{----------------------------}
procedure nnwindow.cmExit(var mess: tmessage);
{----------------------------}
begin
if not (training or running) then tdlgwindow.CmExit(mess)
end;
{----------------------------}
function nnwindow.closelogfile : boolean;
{----------------------------}
begin
if logopen then close(logfile);
logopen := false;
logok := false;
setdlgitemtext(hwindow,ed_userlogfile,'');
closelogfile := true;
{keep copy of old log name}
strcopy(lastlog,logname);
end;
{----------------------------}
function nnwindow.closedatafile : boolean;
{----------------------------}
begin
if datainopen then close(datainfile);
datainopen := false;
dataok := false;
setdlgitemtext(hwindow,ed_userdatafile,'');
closedatafile := true;
end;
{----------------------------}
function nnwindow.killnet : boolean;
{----------------------------}
{ If a modified net exists, asks
before disposing of it.
Returns true if the net is disposed.}
var
ans : word;
mess : Tmessage;
cankill : boolean;
begin
cankill := false;
if (net = nil) then
begin
killnet := true;
netok := false;
exit;
end;
if not modified then cankill := true;
if modified then
begin
ans := messagebox(hwindow,'Do you want to save it ?',
'This net has changed',
mb_yesnocancel or mb_iconhand);
case ans of
id_cancel : cankill := false;
id_yes :
begin
CMsaveasfile(mess);
cankill := true;
end;
id_no : cankill := true;
end;
end;
if cankill then
begin
dispose(net,done);
net := nil;
netok := false;
showicon(sw_hide);
end;
killnet := cankill;
end;
{----------------------------}
procedure nnwindow.CMnewfile(var mess : tmessage);
{----------------------------}
var
ans : integer;
begin
{$ifdef publicdomain}
enablewindow(getdlgitem(hwindow,id_settransfer),false);
enablewindow(getdlgitem(hwindow,id_random),false);
enablemenuitem(getmenu(hwindow),cm_settransfer,mf_bycommand or mf_grayed);
{$endif}
{Throw the old network out and build a new one}
if not (running or training) then
if killnet then
begin
setdlgitemtext(hwindow,ed_netname,'');
strcopy(outname,'');
strcopy(inname,'');
if datainopen then closedatafile;
CMbuildnet(mess);
if net <> nil then
begin
netok := true;
showicon(sw_show);
shownetparams;
settransferfunctions;
end
else
begin
netok := false;
showicon(sw_hide);
report('No Network');
if neuralerror <> 0 then printneuralerror;
{ say('It is best to restart SLUG !');}
end;
end;
end;
{----------------------------}
procedure nnwindow.CMopenfile(var mess : tmessage);
{----------------------------}
{Throw out old net and read a new one}
var
result,save : integer;
begin
if running or training then exit;
{ else, net is now nil.
If If new name chosen, get it from stream. }
strcopy(inname,'*.ann');
if application^.execdialog(new(pfiledialog,init(@self,
pchar(sd_bcfileopen), inname))) = id_ok
then
begin
if not killnet then exit;
strcopy(outname,inname);
new(infile,init(inname,stopenread));
if (infile^.status <> stOK) then
begin
say('Could not open file ! ');
if infile <> nil then dispose(infile,done);
exit;
end;
net := psimplebpnet(infile^.get);
dispose(infile,done);
if (net <> nil) then { net OK}
begin
netok := true;
showicon(sw_show);
shownetparams;
setdlgitemtext(hwindow,ed_netname,inname);
if datainopen then closedatafile;
with initbuffer do
begin
inputsize := net^.inputfield^.count;
outputsize := net^.outputfield^.count;
hiddensize := net^.hiddenfield^.count;
end;
with learnbuffer do
begin
lcoeff := net^.learn;
momentum := net^.momen;
end;
end
else { Net not OK}
begin
say('No network present !');
report('Error');
showicon(sw_hide);
strcopy(inname,'*.ann');
strcopy(outname,'');
setdlgitemtext(hwindow,ed_netname,'');
netok := false;
end;
end;
end;
{----------------------------}
procedure nnwindow.CMsaveasfile(var mess : tmessage);
{----------------------------}
{ Overwrites without asking !
}
begin
if (strlen(outname) = 0) then
strcopy(outname,'*.ann')
else
strcopy(outname,inname);
if application^.execdialog(new(pfiledialog,init(@self,
pchar(sd_bcFileSave), outname))) = id_ok
then
begin
setdlgitemtext(hwindow,ed_netname,outname);
modified := false;
new(outfile,init(outname,stcreate));
if outfile^.status <> stOK then
begin
say('Could not create file ! ');
exit
end;
outfile^.put(net);
dispose(outfile,done);
outfile := nil;
report('Net saved');
end;
{$ifdef debug}
messagebox(hwindow,outname,'File saved as :',mb_ok);
{$endif}
end;
{----------------------------}
procedure nnwindow.CMsavefile(var mess : tmessage);
{----------------------------}
{Simply save}
begin
if (net <>nil) and (strlen(outname)<> 0) then
begin
new(outfile,init(outname,stcreate));
if outfile^.status <> stOK then
begin
say('Could not open file ! ');
Report('Error during stream access');
exit
end;
outfile^.put(net);
dispose(outfile,done);
modified := false;
report('Net written');
end
else
if (net <>nil) then CMsaveasfile(mess);
{$ifdef debug}
messagebox(hwindow,outname,'Written to :',mb_ok);
{$endif}
end;
{-----------------------------------}
procedure nnwindow.CMbuildnet(var mess : tmessage);
{-----------------------------------}
var
edit1, edit2, edit3, edit4 : pnumedit; {numeric edit boxes}
dlg : pspecdialog;
result,discard,i : integer;
procedure builddialog;
begin
new(dlg,init(@self,'netspec1')); {init the dialog }
dlg^.transferbuffer := @initbuffer;
{and the controls}
new(edit1,initresource(dlg,id_netspecin,3,1,999));
new(edit2,initresource(dlg,id_netspecout,3,1,999));
new(edit3,initresource(dlg,id_netspechidden,3,1,999));
{execute the dialog}
result := application^.execdialog(dlg);
if result <= 0 then say('Could not open the dialog');
end;
begin
if killnet then
begin
if datainopen then closedatafile;
builddialog;
if result=idok then with initbuffer do
begin
new(net,init(initbuffer.inputsize,
initbuffer.hiddensize,
initbuffer.outputsize,0.5,0.5));
if net <> nil then
begin
net^.shake(0.10);
report('New network created');
netok := true;
cmsettransfer(mess);
end;
end;
modified := false;
end;
end;
{--------------------------}
procedure nnwindow.CMdatain(var mess : tmessage);
{--------------------------}
begin
if datainopen then closedatafile;
strcopy(datainname,'*.dat');
if application^.execdialog(new(pfiledialog,init(@self,
pchar(sd_bcfileopen), datainname))) = id_ok
then
begin
setdlgitemtext(hwindow,ed_userdatafile,datainname);
dataok := true;
report('Datafile specified');
end
else
begin
strcopy(datainname,'');
dataok := false;
report('Datafile needs to be specified');
end;
end;
{--------------------------}
procedure nnwindow.CMdataout(var mess : tmessage);
{--------------------------}
begin
if logopen
then
if messagebox(hwindow,'Do you want to close it ?','Logfile is open !',
mb_yesno or mb_iconhand) = id_no
then exit
else
begin
closelogfile;
logopen := false;
logok := false;
report('Logfile closed');
end;
strcopy(logname,'*.log');
if application^.execdialog(new(pfiledialog,init(@self,
pchar(sd_bcfileopen), logname))) = id_ok
then
begin
logok := true;
logopen := false;
setdlgitemtext(hwindow,ed_userlogfile,logname);
if chlogappend^.getcheck = bf_checked then logappend := true
else logappend := false;
Report('Logfile specified');
end;
end;
{--------------------------}
procedure NNWindow.SetTransferfunctions;
{--------------------------}
var
thefield : neuronfield;
thefunction : signaltype;
begin
if funcbuffer.hiddentanh = bf_checked then thefunction := tanh;
if funcbuffer.hiddensigmoid = bf_checked then thefunction := sigmoid;
if funcbuffer.hiddenlinear = bf_checked then thefunction := linear;
net^.setfieldsignal(net^.hiddenfield,thefunction);
if funcbuffer.outputtanh = bf_checked then thefunction := tanh;
if funcbuffer.outputsigmoid = bf_checked then thefunction := sigmoid;
if funcbuffer.outputlinear = bf_checked then thefunction := linear;
net^.setfieldsignal(net^.outputfield,thefunction);
end;
{--------------------------}
procedure NNWindow.CMSetTransfer(var mess : tmessage);
{--------------------------}
var
dlg : pdialog;
dlgok : integer;
button : Pradiobutton;
begin
if net=nil then exit;
{$ifdef publicdomain}
net^.setfieldsignal(net^.outputfield,linear);
net^.setfieldsignal(net^.hiddenfield,sigmoid);
exit;
{$endif}
dlg := nil;
{init dialog and controls}
new(dlg,init(@self,'transferdlg'));
if dlg=nil then exit;
new(button,initresource(dlg,id_hiddentanh));
new(button,initresource(dlg,id_hiddensigmoid));
new(button,initresource(dlg,id_hiddenlinear));
new(button,initresource(dlg,id_outputtanh));
new(button,initresource(dlg,id_outputsigmoid));
new(button,initresource(dlg,id_outputlinear));
dlg^.transferbuffer := @funcbuffer;
dlgok := application^.execdialog(dlg);
if dlgok <=0 then
begin
say('Could not open dialog');
exit;
end;
if dlgok = idok then settransferfunctions;
{$IFDEF DEBUG}
printneuralerror;
writeln('Dialog returned ',dlgok);
{$ENDIF}
end;
{--------------------------}
procedure nnwindow.CMtrainparams(var mess: tmessage);
{--------------------------}
var
edit1, edit2, edit3, edit4 : pfloatedit; {numeric edit boxes}
edit5 : pnumedit;
dlg : pspecdialog;
result,discard : integer;
begin
new(dlg,init(@self,'trainparam')); {init the dialog }
dlg^.transferbuffer := @learnbuffer;
{and the controls}
new(edit1,initresource(dlg,ed_userlearn,10,0,100));
new(edit2,initresource(dlg,ed_usermomen,10,0,100));
new(edit3,initresource(dlg,ed_userepoch,10,0,100));
new(edit4,initresource(dlg,ed_usermaxerr,10,0,10));
new(edit5,initresource(dlg,ed_usermaxiter,6,0,100000));
{execute the dialog}
result := application^.execdialog(dlg);
if result <= 0 then
begin
say('Insufficient memory');
exit;
end;
{ else dispose(dlg,done);}
if (net <> nil) and (result=id_ok) then
begin
with learnbuffer do
begin
net^.learn := learnbuffer.lcoeff; { tell the net}
net^.momen := learnbuffer.momentum;
showtrainparams; {tell the user}
end;
end;
end;
{--------------------------}
procedure nnwindow.showtrainparams;
{--------------------------}
{ Redisplays current learning params }
var
str1 : array[0..6] of char;
begin
str1[1] := #0;
if netok then
begin
str(net^.learn:8:3,str1);
setdlgitemtext(hwindow,ed_userlearn,str1);
setdlgitemtext(hwindow,ed_infolearn,str1);
str(net^.momen:8:3,str1);
setdlgitemtext(hwindow,ed_usermomen,str1);
setdlgitemtext(hwindow,ed_infomomen,str1);
strcopy(str1,'None');
setdlgitemtext(hwindow,ed_userepoch,str1);
str(learnbuffer.maxerr:8:3,str1);
setdlgitemtext(hwindow,ed_usermaxerr,str1);
setdlgitemint(hwindow,ed_usermaxiter,learnbuffer.maxiter,false);
end;
end;
{--------------------------}
procedure nnwindow.shownetparams;
{--------------------------}
begin
if net <> nil then
begin
setdlgitemint(hwindow,id_incount,net^.inputfield^.count,false);
setdlgitemint(hwindow,id_hiddencount,net^.hiddenfield^.count,false);
setdlgitemint(hwindow,id_outcount,net^.outputfield^.count,false);
end;
end;
{--------------------------}
procedure nnwindow.CMtrain(var mess: tmessage);
{--------------------------}
begin
if ((dataok) and { If all is set up...}
(logok) and
(net <> nil) and
not training )
then
begin
training := true; {then open the files..}
stopped:= false;
if not datainopen then opentextfile(strpas(datainname),datainfile);
{check for append on logfile}
if not logopen then
if not logappend then
createtextfile(strpas(logname),logfile)
else
appendtextfile(strpas(logname),logfile);
{do some interface stuff}
logopen := true;
datainopen := true;
showwindow(getdlgitem(hwindow,id_readnet), sw_hide);
showwindow(getdlgitem(hwindow,id_dataopen), sw_hide);
showwindow(getdlgitem(hwindow,id_dataclose), sw_hide);
showwindow(getdlgitem(hwindow,id_logopen), sw_hide);
showwindow(getdlgitem(hwindow,id_logclose), sw_hide);
enablewindow(getdlgitem(hwindow,id_cancel),false);
enablemenuitem(getmenu(hwindow),cm_exit,mf_bycommand or mf_grayed);
enablemenuitem(getmenu(hwindow),cm_fileopen,mf_bycommand or mf_grayed);
enablemenuitem(getmenu(hwindow),cm_filenew,mf_bycommand or mf_grayed);
enablemenuitem(getmenu(hwindow),cm_netedit,mf_bycommand or mf_grayed);
drawmenubar(hwindow);
report('Training');
trainsession; {and train}
spacedline(logfile,'Final Weights');
printmattofile(logfile,net^.weights^);
spacedline(logfile,' ');
reset(datainfile);
training:= false;
showwindow(getdlgitem(hwindow,id_readnet), sw_show);
showwindow(getdlgitem(hwindow,id_dataopen), sw_show);
showwindow(getdlgitem(hwindow,id_dataclose), sw_show);
showwindow(getdlgitem(hwindow,id_logopen), sw_show);
showwindow(getdlgitem(hwindow,id_logclose), sw_show);
enablewindow(getdlgitem(hwindow,id_cancel),true);
enablemenuitem(getmenu(hwindow),cm_exit,mf_enabled or mf_bycommand);
enablemenuitem(getmenu(hwindow),cm_filenew,mf_bycommand or mf_enabled);
enablemenuitem(getmenu(hwindow),cm_fileopen,mf_bycommand or mf_enabled);
enablemenuitem(getmenu(hwindow),cm_netedit,mf_bycommand or mf_enabled);
drawmenubar(hwindow);
end
else
begin
messagebeep(mb_iconexclamation);
report('Setup not complete !');
end;
end;
{--------------------------}
procedure nnwindow.trainsession;
{--------------------------}
label quickstop;
var
i,j : word;
count : longint;
lines,linelength : integer;
totalerror,lasterror : double;
Traindata : Trainsteprec;
incount,outcount : integer;
mess : tmsg;
dvin : pdynavec; { for net response after training}
begin
if net = nil then
BEGIN
messagebeep(mb_iconexclamation);
messagebox(hwindow,'','No Network defined !',mb_ok);
exit;
END
else
modified := true;
{ Check out datafile }
readln(datainfile); readln(datainfile);
lines := countlines(datainfile);
readln(datainfile);readln(datainfile); {position correctly...}
{Data interpretation determined
by network structure}
outcount := net^.outputfield^.count;
incount := net^.inputfield^.count;
linelength:= incount + outcount;
{ Make datastructures}
with traindata do
begin
new(DMInput,init(lines,linelength));
new(DMdesired,init(lines,outcount));
new(DVerror,init(outcount,1));
{ Get input data}
if linestomat(datainfile,DMinput^) <> 0 then
begin
dispose(DMInput,done);
dispose(DMdesired,done);
dispose(DVerror,done);
say('Error reading datafile !');
exit;
end;;
writeln(logfile,'IO MATRIX');
printmattofile(logfile,DMinput^);
for i := 1 to lines do
for j := 1 to outcount do
DMdesired^.put(i,j,DMinput^.get(i,incount+j));
writeln(logfile,'DESIRED MATRIX');
printmattofile(logfile,DMdesired^);
for i := 1 to outcount do DMinput^.deletecol(incount+1);
writeln(logfile,'INPUT MATRIX');
printmattofile(logfile,DMinput^);
end;
setupnetparams;
showtrainparams;
{ Start the training...}
count := 0;
totalerror :=9999;
repeat
yield(mess);
edinfocount^.transfer(@count,tf_setdata);
edinfoerror^.transfer(@totalerror,tf_setdata);
count := count +1;
totalerror := TrainEpoch(traindata,lines); {present all data once}
edinfocount^.transfer(@count,tf_setdata);
edinfoerror^.transfer(@totalerror,tf_setdata);
if (count mod 5)=0 then
writeln(logfile,'Event # ',count,totalerror:12:6);
if stopped then
begin
report('Stopped');
totalerror := 0;
spacedline(logfile,' ---- Unexpected Training stop ! -----');
end;
until (totalerror < learnbuffer.maxerr) or
(count > learnbuffer.maxiter);
{finished Training...}
if not stopped then report('Trained !') else report('Unexpected stop');
with traindata do
begin
spacedline(logfile,'Network response: ');
for j := 1 to lines do
begin
dminput^.getrow(j,dvin);
net^.feedforward(dvin);
write(logfile,' inputvec :');
printvectofile(logfile,80,dvin^);
write(logfile,' response : ');
for i := 1 to net^.outputfield^.count do
write(logfile,pneuron(net^.outputfield^.at(i-1))^.output:8:3);
writeln(logfile);
end;
flush(logfile);
quickstop:
dispose(dmdesired,done);
dispose(dminput,done);
dispose(dverror,done);
end;
end;
{----------------------------}
function nnwindow.trainepoch(var data : trainsteprec; count: word) : double;
{----------------------------}
var { Presents count I/O pairs once}
lasterror, totalerror : double;
dvin,dvdesired : pdynavec;
thisone : pneuron;
i,j : integer;
mess : tmsg;
begin
for j := 1 to count do { For each training datum...}
begin
inc(count);
data.DMdesired^.getrow(j,dvdesired); {get data}
data.DMinput^.getrow(j,dvin);
net^.feedforward(dvin); { Feed it forward}
{make error vector}
for i := 1 to net^.outputfield^.count do {...for each output neuron}
begin
yield(mess);
thisone := net^.outputfield^.at(i-1);
lasterror := (dvdesired^.get(i) - thisone^.output);
totalerror := totalerror + abs(lasterror);
data.dverror^.put(i, lasterror);
end; { feed error back}
net^.train(data.dverror);
end;
trainepoch := totalerror;
end;
{----------------------------}
procedure nnwindow.setupnetparams;
{----------------------------}
{ Get data from buffers to the existing net}
begin
if net <> nil then
begin { Setup Backpropnet}
net^.learn := learnbuffer.lcoeff;
net^.momen := learnbuffer.momentum;
end;
end;
{--------------------------}
procedure nnwindow.CMrun(var mess : tmessage);
{--------------------------}
var
DMInput : pdynamat;
DVIn : pdynavec;
lines,i,j : integer;
begin
if (net <> nil) and (dataok) and (logok) then
begin
if not datainopen then
if opentextfile(strpas(datainname),datainfile) <> 0 then exit;
{ if not logopen then
if createtextfile(strpas(logname),logfile) <> 0 then exit;}
if not logopen then
if not logappend then
begin
if createtextfile(strpas(logname),logfile)<>0 then exit;
end
else
if appendtextfile(strpas(logname),logfile)<>0 then exit;
logopen := true;
datainopen := true;
reset(datainfile);
readln(datainfile); readln(datainfile);
lines := countlines(datainfile);
readln(datainfile);readln(datainfile); {position correctly...}
new(dminput,init(lines,net^.inputfield^.count));
spacedline(logfile,' ------ Run Start ------');
{ Get input data}
linestomat(datainfile,DMinput^);
writeln(logfile,'DATA MATRIX');
printmattofile(logfile,DMinput^);
spacedline(logfile,'Network response');
for j := 1 to lines do
begin
dminput^.getrow(j,dvin);
net^.feedforward(dvin);
setdlgitemint(hwindow,ed_infocount,j,false);
printvectofile(logfile,80,dvin^);
for i := 1 to net^.outputfield^.count do
write(logfile,pneuron(net^.outputfield^.at(i-1))^.output:8:3);
writeln(logfile);
end;
flush(logfile);
reset(datainfile);
dispose(dminput,done);
report('Run Complete');
spacedline(logfile,'Run Complete');
end
else
begin
messagebeep(mb_iconexclamation);
report('Setup not complete !');
end;
end;
{--------------------------}
procedure nnwindow.CMdisplay(var mess : tmessage);
{--------------------------}
begin
messagebox(hwindow,'Not implemented','Bad Luck',mb_OK);
end;
{----------------------------}
procedure nnwindow.BNResetweights(var mess : tmessage);
{----------------------------}
begin
if (net <> nil) then
begin
net^.randomweights(0.5);
net^.setconnections;
report('Weights Reset to near zero');
if logopen then spacedline(logfile,'----- Reset ------');
end
end;
{----------------------------}
procedure nnwindow.BNstopnet(var mess : tmessage);
{----------------------------}
{ Flags the running net to stop }
begin
if running or training then
begin
running := false;
training := false;
stopped := true;
end
end;
{----------------------------}
procedure nnwindow.BNsavenet(var mess : tmessage);
{----------------------------}
begin
CMsavefile(mess);
end;
{----------------------------}
procedure nnwindow.BNreadnet(var mess : tmessage);
{----------------------------}
begin
CMopenfile(mess);
end;
{----------------------------}
procedure nnwindow.BNshakenet(var mess : tmessage);
{----------------------------}
begin
if (net <> nil) then net^.shake(1.5);
end;
{----------------------------}
procedure nnwindow.BNtrain(var mess : tmessage);
{----------------------------}
begin
CMTrain(mess);
end;
{----------------------------}
procedure nnwindow.BNSettransfer(var mess : tmessage);
{----------------------------}
begin
CMSetTransfer(mess);
end;
{----------------------------}
procedure nnwindow.showicon(state : word);
{----------------------------}
{Indicates the presence of a valid net}
begin
if (state=sw_hide) or (state=sw_show) then
showwindow(getdlgitem(hwindow,id_icon),state)
end;
{----------------------------}
procedure nnwindow.report(rep:pchar);
{----------------------------}
begin
setdlgitemtext(hwindow,id_status,rep);
end;
{----------------------------}
procedure nnwindow.BNdataopen(var mess : tmessage);
{----------------------------}
begin
cmdatain(mess);
end;
{----------------------------}
procedure nnwindow.BNdataclose(var mess : tmessage);
{----------------------------}
begin
closedatafile;
end;
{----------------------------}
procedure nnwindow.BNlogopen(var mess : tmessage);
{----------------------------}
begin
cmdataout(mess);
end;
{----------------------------}
procedure nnwindow.BNlogclose(var mess : tmessage);
{----------------------------}
begin
closelogfile;
end;
{----------------------------}
procedure nnwindow.BNtrainparams(var mess : tmessage);
{----------------------------}
begin
CMtrainparams(mess);
end;
{----------------------------}
procedure nnwindow.EditFile(pathname : pchar);
{----------------------------}
var
cmdline : array[0..80] of char;
begin {make the filename...}
strpcopy(cmdline,'Notepad.exe ');
strlcat(cmdline,pathname,60);
if winexec(cmdline,sw_show) < 32
then say('Could not find Notepad');
end;
{----------------------------}
procedure nnwindow.BNdataedit(var mess : tmessage);
{----------------------------}
begin
if not dataok then exit else editfile(datainname);
end;
{----------------------------}
procedure nnwindow.BNLogedit(var mess : tmessage);
{----------------------------}
begin
if running or training then exit;
if logok then editfile(logname)
else
if lastlog <> '' then editfile(lastlog);
end;
{----------------------------}
procedure nnwindow.CMAbout(var mess : tmessage);
{----------------------------}
var
dlg : pdialog;
begin
new(dlg,init(@self,'aboutdlg'));
application^.execdialog(dlg);
end;
{----------------------------}
procedure nnwindow.CHrandom(var mess : tmessage);
{----------------------------}
begin
if chrandomdata^.getcheck = bf_checked
then randomdata := true else randomdata := false;
end;
{----------------------------}
procedure nnwindow.CMSlughelp(var mess : tmessage);
{----------------------------}
begin
winhelp(hwindow,'slughlp3.hlp',help_contents,0);
end;
{---------------------- SPECDIALOG PROCEDURES ------------------------}
{----------------------------}
procedure specdialog.zerocounts(var mess : tmessage);
{----------------------------}
var
zero : pchar;
begin
zero := '0';
senddlgitemmsg(id_netspecin, wm_settext,0,longint(zero) );
senddlgitemmsg(id_netspecout, wm_settext,0,longint(zero) );
senddlgitemmsg(id_netspechidden, wm_settext,0,longint(zero) );
end;
{---------------------- APPLICATION PROCEDURES -----------------------}
{----------------------------}
procedure ANNpgm.initmainwindow;
{----------------------------}
begin
mainwindow := new(pNNwindow,init(nil,'ALLIN'));
end;
{======================================== MAIN ====================================================}
var
demo : ANNpgm;
space : longint;
temp : array[0..20] of char;
begin
demo.init('ANN Program 2');
demo.run;
demo.done;
end.
{--------------------------------------- END -----------------------------------------------------}